﻿using Castle.DynamicProxy;
using Common.Attributes;
using Common.Extensions;
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Common.AOP
{
    public class CacheInterceptor : IInterceptor
    {
        private ICaching _cache;

        public CacheInterceptor(ICaching cache)
        {
            _cache = cache;
        }
        public void Intercept(IInvocation invocation)
        {

            //如果方法调用目标不为空就使用方法调用目标,否则使用方法本身,获取自定义的Cacheing特性
            var attribute = (invocation.MethodInvocationTarget ?? invocation.Method).GetCustomAttributes(true).FirstOrDefault(x => x.GetType() == typeof(CachingAttribute)) as CachingAttribute;
            //获取缓存Key
            var cacheKey = _cache.SetCacheKey(invocation);
            //判断key是否为空,判断对应key的缓存是否存在
            if (!string.IsNullOrWhiteSpace(cacheKey) && _cache.Exists(cacheKey))
            {
                //获取缓存
                var value = _cache.GetCache(cacheKey);
                //把缓存赋给方法返回值,然后结束返回
                invocation.ReturnValue = value;
                return;
            }
            invocation.Proceed();
            //缓存
            var options = new MemoryCacheEntryOptions();
            //根据方法上定义的特性的值设置缓存的过期时间和优先级(如果没有定义,就固定30分钟过期,正常优先级)
            options.AbsoluteExpiration = attribute?.AbsoluteExpiration ?? DateTimeOffset.Now.AddMinutes(30);
            options.Priority = attribute?.Priority ?? CacheItemPriority.Normal;
            _cache.SetCache(cacheKey, invocation.ReturnValue, options);
        }
    }
}
